package cool.tianyou.blue.bird.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import com.alibaba.fastjson.JSON;

import cn.hutool.bloomfilter.BitMapBloomFilter;
import cn.hutool.crypto.digest.MD5;
import cool.tianyou.blue.bird.constant.Constant;
import cool.tianyou.blue.bird.model.vo.DeviceMessage;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

import java.util.ArrayList;
import java.util.List;

public class MQTTService extends Service {
    BitMapBloomFilter filter = new BitMapBloomFilter(10);

    public MQTTService() {
    }


    public static final String TAG = MQTTService.class.getSimpleName();

    private MqttAndroidClient client;
    private MqttConnectOptions conOpt;


    private final String clientId = Constant.USER_INFO.DEVICE_INFO;//客户端标识
    private final List<MQTTMessageCallBack> MQTTMessageCallBacks = new ArrayList<>();


    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(getClass().getName(), "onCreate");
        init();
    }

    public void reset() {
        try {
            client.disconnect();
            init();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }


    private void init() {
        // 服务器地址（协议+地址+端口号）
        String uri = "tcp://47.94.211.190:1883";
        client = new MqttAndroidClient(this, uri, clientId);
        // 设置MQTT监听并且接受消息
        client.setCallback(mqttCallback);
        conOpt = new MqttConnectOptions();
        // 清除缓存
        conOpt.setCleanSession(true);
        // 设置超时时间，单位：秒
        conOpt.setConnectionTimeout(10);
        // 心跳包发送间隔，单位：秒
        conOpt.setKeepAliveInterval(20);
        // 用户名
        String userName = "mobile_client";
        conOpt.setUserName(userName);
        // 密码
        String password = "WWf1XE0CkrTzcBi06NhORgEwcQKcCgZHGioyxBIQ";
        conOpt.setPassword(password.toCharArray());     //将字符串转换为字符串数组

        // last will message
        boolean doConnect = true;
        String message = "{\"terminal_uid\":\"" + clientId + "\"}";
        Log.e(getClass().getName(), "message是:" + message);
        String topic = genTopic();
        int qos = 0;
        Boolean retained = false;
        if ((!message.equals("")) || (!topic.equals(""))) {
            try {
                conOpt.setWill(topic, message.getBytes(), (int) qos, retained.booleanValue());
            } catch (Exception e) {
                Log.i(TAG, "Exception Occured", e);
                doConnect = false;
                iMqttActionListener.onFailure(null, e);
            }
        }

        if (doConnect) {
            doClientConnection();
        }

    }

    public String genTopic() {
        return "DOVE/" + Constant.USER_INFO.USER_ID + "/" + MD5.create().digestHex16(Constant.USER_INFO.TOKEN);
    }


    @Override
    public void onDestroy() {
        stopSelf();

        try {
            client.unregisterResources();
            client.disconnect();
        } catch (MqttException e) {
            e.printStackTrace();
        }
        Log.i("MQTT service销毁", "");
        super.onDestroy();
    }

    /**
     * 连接MQTT服务器
     */
    private void doClientConnection() {
        if (!client.isConnected() && isConnectIsNormal()) {
            try {
                client.connect(conOpt, null, iMqttActionListener);
            } catch (MqttException e) {
                Log.e("MQTT出现错误", String.valueOf(e.getMessage()));
                e.printStackTrace();
            }
        }

    }

    // MQTT是否连接成功
    private final IMqttActionListener iMqttActionListener = new IMqttActionListener() {

        @Override
        public void onSuccess(IMqttToken arg0) {
            Log.i(TAG, "连接成功 ");
            try {
                String topic = genTopic();
                Log.i("监听消息topic", topic);
                client.subscribe(topic, 1);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(IMqttToken arg0, Throwable arg1) {
            arg1.printStackTrace();
            doClientConnection();
        }
    };

    // MQTT监听并且接受消息
    private final MqttCallback mqttCallback = new MqttCallback() {
        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {

            DeviceMessage deviceMessage = JSON.parseObject(new String(message.getPayload()), DeviceMessage.class);
            Log.e("收到消息:" + TAG, topic);
            Log.e(TAG, message.toString());
            if (!MQTTMessageCallBacks.isEmpty()) {
                if (filter.contains(deviceMessage.getMessageId())) {
                    return;
                }
                filter.add(deviceMessage.getMessageId());
                for (MQTTMessageCallBack MQTTMessageCallBack : MQTTMessageCallBacks) {
                    MQTTMessageCallBack.setMessage(deviceMessage);
                }
            }
            String str2 = topic + ";qos:" + message.getQos() + ";retained:" + message.isRetained();
            Log.i(TAG, "messageArrived:" + deviceMessage);
            Log.i(TAG, str2);
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken arg0) {

        }

        @Override
        public void connectionLost(Throwable arg0) {
            doClientConnection();
        }
    };

    /**
     * 判断网络是否连接
     */
    private boolean isConnectIsNormal() {
        ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext()
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connectivityManager.getActiveNetworkInfo();
        if (info != null && info.isAvailable()) {
            String name = info.getTypeName();
            Log.i(TAG, "MQTT当前网络名称：" + name);
            return true;
        } else {
            Log.i(TAG, "MQTT 没有可用网络");
            return false;
        }
    }


    @Override
    public IBinder onBind(Intent intent) {
        Log.e(getClass().getName(), "onBind");
        return new CustomBinder();
    }

    public void addIGetMessageCallBack(MQTTMessageCallBack MQTTMessageCallBack) {
        this.MQTTMessageCallBacks.add(MQTTMessageCallBack);
    }

    public class CustomBinder extends Binder {
        public MQTTService getService() {
            return MQTTService.this;
        }
    }


}